package com.abbas.smartCity.okhttp;

import android.os.Handler;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.abbas.smartCity.App;
import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * java版本的OkHttp封装
 * 使用示例：
 * @see com.abbas.smartCity.ui.TestActivity
 *
 * 哎，不会kotlin的痛苦
 */
public class OkGo {

    /**
     * OkHttpClient
     */
    private static final OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @NonNull
                @Override
                public Response intercept(@NonNull Chain chain) throws IOException {
                    return chain.proceed(chain.request());
                }
            }).build();

    //线程切换handler
    private static final Handler handler = App.getHandler();

    /**
     * 发起一个get请求
     * @param suffixUrl 详细地址
     * @param clazz 数据bean类
     * @param callback 回调
     * @param <T> 数据bean类
     */
    public static <T> void get(String suffixUrl,Class<T> clazz,OkGoCallback<T> callback){
        final Request request = new Request.Builder()
                .url(App.getBaseUrl() + suffixUrl)
                .addHeader("Authorization", Objects.requireNonNull(App.getSharedPreferences().getString("token", "")))
                .build();
        execute(request,clazz,callback);
    }

    /**
     * 发起一个post请求
     * @param suffixUrl 详细地址
     * @param paramsMap 上传的键值对
     * @param clazz 数据bean类
     * @param callback 回调
     * @param <T> 数据bean类
     */
    public static <T> void post(String suffixUrl, Map<String,Object> paramsMap, Class<T> clazz, OkGoCallback<T> callback){
        final Request request = new Request.Builder()
                .url(App.getBaseUrl() + suffixUrl)
                .addHeader("Authorization", Objects.requireNonNull(App.getSharedPreferences().getString("token", "")))
                .post(RequestBody.create(MediaType.parse("application/json"),new Gson().toJson(paramsMap)))
                .build();
        execute(request,clazz,callback);
    }

    /**
     * 发起一个post请求
     * @param suffixUrl 详细地址
     * @param obj 上传的对象
     * @param clazz 数据bean类
     * @param callback 回调
     * @param <T> 数据bean类
     */
    public static <T> void post(String suffixUrl, Object obj, Class<T> clazz, OkGoCallback<T> callback){
        final Request request = new Request.Builder()
                .url(App.getBaseUrl() + suffixUrl)
                .addHeader("Authorization", Objects.requireNonNull(App.getSharedPreferences().getString("token", "")))
                .post(RequestBody.create(MediaType.parse("application/json"),new Gson().toJson(obj)))
                .build();
        execute(request,clazz,callback);
    }

    /**
     * 发起一个put请求
     * @param suffixUrl
     * @param paramsMap
     * @param clazz
     * @param callback
     * @param <T>
     */
    public static <T> void put(String suffixUrl, Map<String,Object> paramsMap, Class<T> clazz, OkGoCallback<T> callback){
        final Request request = new Request.Builder()
                .url(App.getBaseUrl() + suffixUrl)
                .addHeader("Authorization", Objects.requireNonNull(App.getSharedPreferences().getString("token", "")))
                .put(RequestBody.create(MediaType.parse("application/json"),new Gson().toJson(paramsMap)))
                .build();
        execute(request,clazz,callback);
    }

    /**
     * 发起一个put请求
     * @param suffixUrl
     * @param obj
     * @param clazz
     * @param callback
     * @param <T>
     */
    public static <T> void put(String suffixUrl, Object obj, Class<T> clazz, OkGoCallback<T> callback){
        final Request request = new Request.Builder()
                .url(App.getBaseUrl() + suffixUrl)
                .addHeader("Authorization", Objects.requireNonNull(App.getSharedPreferences().getString("token", "")))
                .put(RequestBody.create(MediaType.parse("application/json"),new Gson().toJson(obj)))
                .build();
        execute(request,clazz,callback);
    }

    /**
     * 启动访问
     * @param request 请求
     * @param clazz 数据bean类
     * @param callback 回调
     * @param <T> 数据bean类
     */
    private static <T> void execute(Request request,Class<T> clazz,OkGoCallback<T> callback){
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                handler.post(() -> Toast.makeText(App.getContext(),"网络异常，请检查网络",Toast.LENGTH_SHORT).show());
                callback.onFailure("网络异常，请检查网络");
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful()){
                    if (response.body() != null){
                        try {
                            final String jsonData = response.body().string();
                            JSONObject jsonRes = new JSONObject(jsonData);
                            int resCode = jsonRes.optInt("code");
                            String resMsg = jsonRes.optString("msg");
                            handler.post(() -> {
                                if (resCode >= 200 && resCode <= 299){
                                    callback.onSuccess(call,App.gson.fromJson(jsonData,clazz));
                                }else if (resCode >= 500 && resCode <= 599){
                                    callback.onFailure(resMsg);
                                }
                            });
                        } catch (JSONException e) {
                            handler.post(() -> {
                                callback.onFailure("服务器数据解析失败！");
                            });
                            throw new RuntimeException(e);
                        }
                    }
                }else {
                    handler.post(() -> Toast.makeText(App.getContext(),"请求异常，请检查网络。"+response.message(),Toast.LENGTH_SHORT).show());
                }
            }
        });
    }

}
